package com.onlyxiahui.aware.run.common.log4j2;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.AppenderRef;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**
 * 
 * <br>
 * Date 2019-11-27 11:10:59<br>
 * 
 * @author XiaHui [onlovexiahui@qq.com]<br>
 * @since 1.0.0
 */
@Component
public class Log4j2Refresh {

	String key = "spring.aware.log4j2.loggers";

	String nameKey = "name";
	String levelKey = "level";

	@Autowired(required = false)
	private Environment environment;

	/**
	 * 监听配置变更事件，只处理关于日志的配置，其它忽略即可。
	 *
	 * <pre>
	 * [
	 *     {
	 *         "name": "com.onlyxiahui",
	 *         "level": "info"
	 *     },
	 *     {
	 *         "name": "root",
	 *         "level": "info"
	 *     }
	 * ]
	 * </pre>
	 */

	@PostConstruct
	private void initialize() {
		if (null != environment) {
			String loggers = environment.getProperty(key);
			refreshLoggingLevels(loggers);
		}
	}

	public boolean maybeJsonArray(String string) {
		string = (null == string) ? string : string.trim();
		return string != null && ("null".equals(string) || (string.startsWith("[") && string.endsWith("]")));
	}

	public void refreshLoggingLevels(String loggers) {
		if (maybeJsonArray(loggers)) {
			try {
				JSONArray ja = JSONArray.parseArray(loggers);
				int size = ja.size();

				if (size > 0) {
					// 获取日志配置上下文
					final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
					final Configuration config = ctx.getConfiguration();

					for (int i = 0; i < size; i++) {
						Object o = ja.get(i);
						if (o instanceof JSONObject) {
							JSONObject jo = (JSONObject) o;
							if (jo.isEmpty()) {
								continue;
							}

							String name = jo.getString(nameKey);
							String level = jo.getString(levelKey);
							// 如果是缺省配置则要另行处理
							if (LoggerConfig.ROOT.equals(name)) {
								name = LogManager.ROOT_LOGGER_NAME;
							}
							// 找到匹配的记录器
							LoggerConfig loggerConfig = config.getLoggerConfig(name);

							if (null != loggerConfig && loggerConfig.getName().equals(name)) {
								// 动态修改值
								loggerConfig.setLevel(Level.valueOf(level));
							} else {
								Map<String, Appender> map = config.getAppenders();
								List<AppenderRef> list = new ArrayList<>();
								if (null != map) {
									for (Map.Entry<String, Appender> e : map.entrySet()) {
										String k = e.getKey();
//										Appender a = e.getValue();
										list.add(AppenderRef.createAppenderRef(k, Level.valueOf(level), null));
									}
								}
								AppenderRef[] refs = list.toArray(new AppenderRef[list.size()]);
								loggerConfig = LoggerConfig.createLogger(false, Level.valueOf(level), name, "true", refs, null, config, null);
								config.addLogger(name, loggerConfig);
							}
						}
					}
					// 刷新配置
					ctx.updateLoggers();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}
